home *** CD-ROM | disk | FTP | other *** search
/ Mac Format 1995 June / MacFormat 25.iso / Shareware City / Developers / OutOfPhase1.1 Source / OutOfPhase Folder / LFOGenerator.c < prev    next >
Text File  |  1995-01-04  |  50KB  |  1,664 lines

  1. /* LFOGenerator.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    Out Of Phase:  Digital Music Synthesis on General Purpose Computers    */
  5. /*    Copyright (C) 1994  Thomas R. Lawrence                                 */
  6. /*                                                                           */
  7. /*    This program is free software; you can redistribute it and/or modify   */
  8. /*    it under the terms of the GNU General Public License as published by   */
  9. /*    the Free Software Foundation; either version 2 of the License, or      */
  10. /*    (at your option) any later version.                                    */
  11. /*                                                                           */
  12. /*    This program is distributed in the hope that it will be useful,        */
  13. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  14. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
  15. /*    GNU General Public License for more details.                           */
  16. /*                                                                           */
  17. /*    You should have received a copy of the GNU General Public License      */
  18. /*    along with this program; if not, write to the Free Software            */
  19. /*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
  20. /*                                                                           */
  21. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  22. /*                                                                           */
  23. /*****************************************************************************/
  24.  
  25. #include "MiscInfo.h"
  26. #include "Audit.h"
  27. #include "Debug.h"
  28. #include "Definitions.h"
  29.  
  30. #include "LFOGenerator.h"
  31. #include "Memory.h"
  32. #include "EnvelopeState.h"
  33. #include "LFOSpecifier.h"
  34. #include "LFOListSpecifier.h"
  35. #include "FloatingPoint.h"
  36. #include "RandomNumbers.h"
  37. #include "Frequency.h"
  38. #include "Multisampler.h"
  39. #include "64BitMath.h"
  40. #include "SampleConsts.h"
  41. #include "WaveIndexUtility.h"
  42.  
  43.  
  44. #define TWOPI ((float)6.28318530717958648)
  45.  
  46.  
  47. typedef struct LFOOneStateRec
  48.     {
  49.         /* pointer to the LFO generating function */
  50.         float                                        (*GenFunction)(struct LFOOneStateRec* State, float Phase,
  51.                                                             float OriginalValue, float Amplitude);
  52.  
  53.         /* phase index counter */
  54.         FastFixedType                        CurrentPhase;
  55.  
  56.         /* the envelope controlling the amplitude. */
  57.         EvalEnvelopeRec*                LFOAmplitudeEnvelope;
  58.         /* the envelope controlling the frequency.  the value from here is periods per second */
  59.         EvalEnvelopeRec*                LFOFrequencyEnvelope;
  60.  
  61.         /* if this is True, then modulation is linear, otherwise modulation is */
  62.         /* exponential */
  63.         LFOArithSelect                    ModulationMode;
  64.  
  65.         /* what kind of operator are we using */
  66.         LFOOscTypes                            Operator;
  67.  
  68.         /* source information for the wave table */
  69.         MultiSampleRec*                    WaveTableSourceSelector;
  70.  
  71.         /* this is true if the wave table was defined */
  72.         MyBoolean                                WaveTableWasDefined;
  73.         /* number of frames per table */
  74.         long                                        FramesPerTable;
  75.         /* number of tables */
  76.         long                                        NumberOfTables;
  77.         /* raw wave table data array */
  78.         void**                                    WaveTableMatrix;
  79.         /* function for indexing the wave table */
  80.         signed long                            (*WaveIndexer)(float Phase, FastFixedType TableIndex,
  81.                                                             long NumTables, long Frames, void** Matrix);
  82.         /* number of bits in the data for the table */
  83.         NumBitsType                            TableNumBits;
  84.         /* envelope controlling wave table index */
  85.         EvalEnvelopeRec*                WaveTableIndexEnvelope;
  86.  
  87.         /* modulation method */
  88.         LFOModulationTypes            ModulationMethod;
  89.  
  90.         /* special extra value */
  91.         double                                    ExtraValue;
  92.         /* envelope ticks per second */
  93.         float                                        TicksPerSecond;
  94.         /* previous noise value */
  95.         float                                        LeftNoise;
  96.         /* next noise value */
  97.         float                                        RightNoise;
  98.         /* random number generator seed */
  99.         long                                        RandomSeed;
  100.  
  101.         /* link to the next one */
  102.         struct LFOOneStateRec*    Next;
  103.     } LFOOneStateRec;
  104.  
  105.  
  106. struct LFOGenRec
  107.     {
  108.         /* list of single LFO entries, which we sum up. */
  109.         LFOOneStateRec*                    LFOList;
  110.  
  111.         /* number of envelope clock pulses per second */
  112.         float                                        EnvelopeTicksPerSecond;
  113.  
  114.         /* link for caching records */
  115.         LFOGenRec*                            GarbageLink;
  116.     };
  117.  
  118.  
  119. /* prototypes */
  120. static float                        AddConst(LFOOneStateRec* State, float Phase,
  121.                                                     float OriginalValue, float Amplitude);
  122. static float                        AddSignSine(LFOOneStateRec* State, float Phase,
  123.                                                     float OriginalValue, float Amplitude);
  124. static float                        AddPosSine(LFOOneStateRec* State, float Phase,
  125.                                                     float OriginalValue, float Amplitude);
  126. static float                        AddSignTriangle(LFOOneStateRec* State, float Phase,
  127.                                                     float OriginalValue, float Amplitude);
  128. static float                        AddPosTriangle(LFOOneStateRec* State, float Phase,
  129.                                                     float OriginalValue, float Amplitude);
  130. static float                        AddSignSquare(LFOOneStateRec* State, float Phase,
  131.                                                     float OriginalValue, float Amplitude);
  132. static float                        AddPosSquare(LFOOneStateRec* State, float Phase,
  133.                                                     float OriginalValue, float Amplitude);
  134. static float                        AddSignRamp(LFOOneStateRec* State, float Phase,
  135.                                                     float OriginalValue, float Amplitude);
  136. static float                        AddPosRamp(LFOOneStateRec* State, float Phase,
  137.                                                     float OriginalValue, float Amplitude);
  138. static float                        AddSignFuzzTriangle(LFOOneStateRec* State, float Phase,
  139.                                                     float OriginalValue, float Amplitude);
  140. static float                        AddPosFuzzTriangle(LFOOneStateRec* State, float Phase,
  141.                                                     float OriginalValue, float Amplitude);
  142. static float                        AddSignFuzzSquare(LFOOneStateRec* State, float Phase,
  143.                                                     float OriginalValue, float Amplitude);
  144. static float                        AddPosFuzzSquare(LFOOneStateRec* State, float Phase,
  145.                                                     float OriginalValue, float Amplitude);
  146. static float                        AddWaveTable(LFOOneStateRec* State, float Phase,
  147.                                                     float OriginalValue, float Amplitude);
  148. static float                        MultConst(LFOOneStateRec* State, float Phase,
  149.                                                     float OriginalValue, float Amplitude);
  150. static float                        MultSignSine(LFOOneStateRec* State, float Phase,
  151.                                                     float OriginalValue, float Amplitude);
  152. static float                        MultPosSine(LFOOneStateRec* State, float Phase,
  153.                                                     float OriginalValue, float Amplitude);
  154. static float                        MultSignTriangle(LFOOneStateRec* State, float Phase,
  155.                                                     float OriginalValue, float Amplitude);
  156. static float                        MultPosTriangle(LFOOneStateRec* State, float Phase,
  157.                                                     float OriginalValue, float Amplitude);
  158. static float                        MultSignSquare(LFOOneStateRec* State, float Phase,
  159.                                                     float OriginalValue, float Amplitude);
  160. static float                        MultPosSquare(LFOOneStateRec* State, float Phase,
  161.                                                     float OriginalValue, float Amplitude);
  162. static float                        MultSignRamp(LFOOneStateRec* State, float Phase,
  163.                                                     float OriginalValue, float Amplitude);
  164. static float                        MultPosRamp(LFOOneStateRec* State, float Phase,
  165.                                                     float OriginalValue, float Amplitude);
  166. static float                        MultSignFuzzTriangle(LFOOneStateRec* State, float Phase,
  167.                                                     float OriginalValue, float Amplitude);
  168. static float                        MultPosFuzzTriangle(LFOOneStateRec* State, float Phase,
  169.                                                     float OriginalValue, float Amplitude);
  170. static float                        MultSignFuzzSquare(LFOOneStateRec* State, float Phase,
  171.                                                     float OriginalValue, float Amplitude);
  172. static float                        MultPosFuzzSquare(LFOOneStateRec* State, float Phase,
  173.                                                     float OriginalValue, float Amplitude);
  174. static float                        MultWaveTable(LFOOneStateRec* State, float Phase,
  175.                                                     float OriginalValue, float Amplitude);
  176. static float                        InvMultConst(LFOOneStateRec* State, float Phase,
  177.                                                     float OriginalValue, float Amplitude);
  178. static float                        InvMultSignSine(LFOOneStateRec* State, float Phase,
  179.                                                     float OriginalValue, float Amplitude);
  180. static float                        InvMultPosSine(LFOOneStateRec* State, float Phase,
  181.                                                     float OriginalValue, float Amplitude);
  182. static float                        InvMultSignTriangle(LFOOneStateRec* State, float Phase,
  183.                                                     float OriginalValue, float Amplitude);
  184. static float                        InvMultPosTriangle(LFOOneStateRec* State, float Phase,
  185.                                                     float OriginalValue, float Amplitude);
  186. static float                        InvMultSignSquare(LFOOneStateRec* State, float Phase,
  187.                                                     float OriginalValue, float Amplitude);
  188. static float                        InvMultPosSquare(LFOOneStateRec* State, float Phase,
  189.                                                     float OriginalValue, float Amplitude);
  190. static float                        InvMultSignRamp(LFOOneStateRec* State, float Phase,
  191.                                                     float OriginalValue, float Amplitude);
  192. static float                        InvMultPosRamp(LFOOneStateRec* State, float Phase,
  193.                                                     float OriginalValue, float Amplitude);
  194. static float                        InvMultSignFuzzTriangle(LFOOneStateRec* State, float Phase,
  195.                                                     float OriginalValue, float Amplitude);
  196. static float                        InvMultPosFuzzTriangle(LFOOneStateRec* State, float Phase,
  197.                                                     float OriginalValue, float Amplitude);
  198. static float                        InvMultSignFuzzSquare(LFOOneStateRec* State, float Phase,
  199.                                                     float OriginalValue, float Amplitude);
  200. static float                        InvMultPosFuzzSquare(LFOOneStateRec* State, float Phase,
  201.                                                     float OriginalValue, float Amplitude);
  202. static float                        InvMultWaveTable(LFOOneStateRec* State, float Phase,
  203.                                                     float OriginalValue, float Amplitude);
  204.  
  205.  
  206. static LFOGenRec*                    LFOGenFreeList = NIL;
  207. static LFOOneStateRec*        LFOOneStateFreeList = NIL;
  208.  
  209.  
  210. /* flush cached LFO generator records */
  211. void                                FlushLFOGeneratorRecords(void)
  212.     {
  213.         while (LFOGenFreeList != NIL)
  214.             {
  215.                 LFOGenRec*                Temp;
  216.  
  217.                 Temp = LFOGenFreeList;
  218.                 LFOGenFreeList = LFOGenFreeList->GarbageLink;
  219.                 ReleasePtr((char*)Temp);
  220.             }
  221.  
  222.         while (LFOOneStateFreeList != NIL)
  223.             {
  224.                 LFOOneStateRec*        Temp;
  225.  
  226.                 Temp = LFOOneStateFreeList;
  227.                 LFOOneStateFreeList = LFOOneStateFreeList->Next;
  228.                 ReleasePtr((char*)Temp);
  229.             }
  230.     }
  231.  
  232.  
  233. #if DEBUG
  234. static void                    ValidateLFOGen(LFOGenRec* LFOGen)
  235.     {
  236.         LFOGenRec*                Scan;
  237.  
  238.         Scan = LFOGenFreeList;
  239.         while (Scan != NIL)
  240.             {
  241.                 if (Scan == LFOGen)
  242.                     {
  243.                         PRERR(ForceAbort,"ValidateLFOGen:  it's on the free list");
  244.                     }
  245.                 Scan = Scan->GarbageLink;
  246.             }
  247.     }
  248. #else
  249. #define ValidateLFOGen(x) ((void)0)
  250. #endif
  251.  
  252.  
  253. #if DEBUG
  254. static void                    ValidateLFOOneState(LFOOneStateRec* OneState)
  255.     {
  256.         LFOOneStateRec*        Scan;
  257.  
  258.         Scan = LFOOneStateFreeList;
  259.         while (Scan != NIL)
  260.             {
  261.                 if (Scan == OneState)
  262.                     {
  263.                         PRERR(ForceAbort,"ValidateLFOOneState:  it's on the free list");
  264.                     }
  265.                 Scan = Scan->Next;
  266.             }
  267.     }
  268. #else
  269. #define ValidateLFOOneState(x) ((void)0)
  270. #endif
  271.  
  272.  
  273. /* create a new LFO generator based on a list of specifications */
  274. /* it returns the largest pre-origin time for all of the envelopes it contains */
  275. /* AmplitudeScaling and FrequencyScaling are provided primarily for frequency */
  276. /* LFO control; other LFOs are controlled through the accent parameters, and */
  277. /* should supply 1 (no scaling) for these parameters. */
  278. LFOGenRec*                    NewLFOGenerator(struct LFOListSpecRec* LFOListSpec,
  279.                                             long* MaxPreOriginTime, float Accent1, float Accent2,
  280.                                             float Accent3, float Accent4, float FrequencyHertz,
  281.                                             float HurryUp, float TicksPerSecond, float AmplitudeScaling,
  282.                                             float FrequencyScaling, float FreqForMultisampling)
  283.     {
  284.         LFOGenRec*                LFOGen;
  285.         long                            ListLimit;
  286.         long                            ListScan;
  287.         LFOOneStateRec*        ListTail;
  288.         long                            MaxPreOrigin;
  289.  
  290.         CheckPtrExistence(LFOListSpec);
  291.         if (LFOGenFreeList != NIL)
  292.             {
  293.                 LFOGen = LFOGenFreeList;
  294.                 LFOGenFreeList = LFOGenFreeList->GarbageLink;
  295.             }
  296.          else
  297.             {
  298.                 LFOGen = (LFOGenRec*)AllocPtrCanFail(sizeof(LFOGenRec),"LFOGenRec");
  299.                 if (LFOGen == NIL)
  300.                     {
  301.                         return NIL;
  302.                     }
  303.             }
  304.  
  305.         /* remember the envelope rate */
  306.         LFOGen->EnvelopeTicksPerSecond = TicksPerSecond;
  307.  
  308.         /* build the list of thingers */
  309.         LFOGen->LFOList = NIL;
  310.         ListTail = NIL;
  311.         ListLimit = LFOListSpecGetNumElements(LFOListSpec);
  312.         MaxPreOrigin = 0;
  313.         for (ListScan = 0; ListScan < ListLimit; ListScan += 1)
  314.             {
  315.                 LFOSpecRec*                OneLFOSpec;
  316.                 LFOOneStateRec*        ListNode;
  317.                 long                            PreOriginTime;
  318.  
  319.                 /* allocate an entry */
  320.                 if (LFOOneStateFreeList != NIL)
  321.                     {
  322.                         ListNode = LFOOneStateFreeList;
  323.                         LFOOneStateFreeList = LFOOneStateFreeList->Next;
  324.                     }
  325.                  else
  326.                     {
  327.                         ListNode = (LFOOneStateRec*)AllocPtrCanFail(sizeof(LFOOneStateRec),
  328.                             "LFOOneStateRec");
  329.                         if (ListNode == NIL)
  330.                             {
  331.                              FailurePoint1:
  332.                                 while (LFOGen->LFOList != NIL)
  333.                                     {
  334.                                         ListNode = LFOGen->LFOList;
  335.                                         LFOGen->LFOList = LFOGen->LFOList->Next;
  336.                                         DisposeEnvelopeStateRecord(ListNode->LFOAmplitudeEnvelope);
  337.                                         DisposeEnvelopeStateRecord(ListNode->LFOFrequencyEnvelope);
  338.                                         ListNode->Next = LFOOneStateFreeList;
  339.                                         LFOOneStateFreeList = ListNode;
  340.                                     }
  341.                                 LFOGen->GarbageLink = LFOGenFreeList;
  342.                                 LFOGenFreeList = LFOGen;
  343.                                 return NIL;
  344.                             }
  345.                     }
  346.                 /* initialize phase index */
  347.                 ListNode->CurrentPhase = 0;
  348.                 /* get the data to put in it */
  349.                 OneLFOSpec = LFOListSpecGetLFOSpec(LFOListSpec,ListScan);
  350.                 /* Add frequency envelope generator */
  351.                 ListNode->LFOFrequencyEnvelope = NewEnvelopeStateRecord(
  352.                     GetLFOSpecFrequencyEnvelope(OneLFOSpec),Accent1,Accent2,Accent3,Accent4,
  353.                     FrequencyHertz,FrequencyScaling,HurryUp,TicksPerSecond,&PreOriginTime);
  354.                 if (ListNode->LFOFrequencyEnvelope == NIL)
  355.                     {
  356.                      FailurePoint2:
  357.                         ListNode->Next = LFOOneStateFreeList;
  358.                         LFOOneStateFreeList = ListNode;
  359.                         goto FailurePoint1;
  360.                     }
  361.                 if (PreOriginTime > MaxPreOrigin)
  362.                     {
  363.                         MaxPreOrigin = PreOriginTime;
  364.                     }
  365.                 /* determine what mode to use and calculate amplitude */
  366.                 switch (LFOSpecGetAddingMode(OneLFOSpec))
  367.                     {
  368.                         default:
  369.                             EXECUTE(PRERR(ForceAbort,
  370.                                 "NewLFOGenerator:  bad value from LFOSpecGetAddingMode"));
  371.                             break;
  372.                         case eLFOArithmetic:
  373.                             ListNode->ModulationMode = eLFOArithAdditive;
  374.                             break;
  375.                         case eLFOGeometric:
  376.                             ListNode->ModulationMode = eLFOArithGeometric;
  377.                             break;
  378.                         case eLFOHalfSteps:
  379.                             ListNode->ModulationMode = eLFOArithHalfSteps;
  380.                             break;
  381.                     }
  382.                 /* add the amplitude envelope generator */
  383.                 ListNode->LFOAmplitudeEnvelope = NewEnvelopeStateRecord(
  384.                     GetLFOSpecAmplitudeEnvelope(OneLFOSpec),Accent1,Accent2,Accent3,Accent4,
  385.                     FrequencyHertz,AmplitudeScaling,HurryUp,TicksPerSecond,&PreOriginTime);
  386.                 if (ListNode->LFOAmplitudeEnvelope == NIL)
  387.                     {
  388.                      FailurePoint3:
  389.                         DisposeEnvelopeStateRecord(ListNode->LFOFrequencyEnvelope);
  390.                         goto FailurePoint2;
  391.                     }
  392.                 if (PreOriginTime > MaxPreOrigin)
  393.                     {
  394.                         MaxPreOrigin = PreOriginTime;
  395.                     }
  396.                 /* determine what function to use */
  397.                 ListNode->Operator = LFOSpecGetOscillatorType(OneLFOSpec);
  398.                 ListNode->ModulationMethod = LFOSpecGetModulationMode(OneLFOSpec);
  399.                 switch (ListNode->Operator)
  400.                     {
  401.                         default:
  402.                             EXECUTE(PRERR(ForceAbort,"NewLFOGenerator:  bad oscillator type"));
  403.                             break;
  404.                         case eLFOConstant1:
  405.                             switch (ListNode->ModulationMethod)
  406.                                 {
  407.                                     default:
  408.                                         EXECUTE(PRERR(ForceAbort,"NewLFOGenerator:  bad modulation type"));
  409.                                         break;
  410.                                     case eLFOAdditive:
  411.                                         ListNode->GenFunction = &AddConst;
  412.                                         break;
  413.                                     case eLFOMultiplicative:
  414.                                         ListNode->GenFunction = &MultConst;
  415.                                         break;
  416.                                     case eLFOInverseMultiplicative:
  417.                                         ListNode->GenFunction = &InvMultConst;
  418.                                         break;
  419.                                 }
  420.                             break;
  421.                         case eLFOSignedSine:
  422.                             switch (ListNode->ModulationMethod)
  423.                                 {
  424.                                     default:
  425.                                         EXECUTE(PRERR(ForceAbort,"NewLFOGenerator:  bad modulation type"));
  426.                                         break;
  427.                                     case eLFOAdditive:
  428.                                         ListNode->GenFunction = &AddSignSine;
  429.                                         break;
  430.                                     case eLFOMultiplicative:
  431.                                         ListNode->GenFunction = &MultSignSine;
  432.                                         break;
  433.                                     case eLFOInverseMultiplicative:
  434.                                         ListNode->GenFunction = &InvMultSignSine;
  435.                                         break;
  436.                                 }
  437.                             break;
  438.                         case eLFOPositiveSine:
  439.                             switch (ListNode->ModulationMethod)
  440.                                 {
  441.                                     default:
  442.                                         EXECUTE(PRERR(ForceAbort,"NewLFOGenerator:  bad modulation type"));
  443.                                         break;
  444.                                     case eLFOAdditive:
  445.                                         ListNode->GenFunction = &AddPosSine;
  446.                                         break;
  447.                                     case eLFOMultiplicative:
  448.                                         ListNode->GenFunction = &MultPosSine;
  449.                                         break;
  450.                                     case eLFOInverseMultiplicative:
  451.                                         ListNode->GenFunction = &InvMultPosSine;
  452.                                         break;
  453.                                 }
  454.                             break;
  455.                         case eLFOSignedTriangle:
  456.                             switch (ListNode->ModulationMethod)
  457.                                 {
  458.                                     default:
  459.                                         EXECUTE(PRERR(ForceAbort,"NewLFOGenerator:  bad modulation type"));
  460.                                         break;
  461.                                     case eLFOAdditive:
  462.                                         ListNode->GenFunction = &AddSignTriangle;
  463.                                         break;
  464.                                     case eLFOMultiplicative:
  465.                                         ListNode->GenFunction = &MultSignTriangle;
  466.                                         break;
  467.                                     case eLFOInverseMultiplicative:
  468.                                         ListNode->GenFunction = &InvMultSignTriangle;
  469.                                         break;
  470.                                 }
  471.                             break;
  472.                         case eLFOPositiveTriangle:
  473.                             switch (ListNode->ModulationMethod)
  474.                                 {
  475.                                     default:
  476.                                         EXECUTE(PRERR(ForceAbort,"NewLFOGenerator:  bad modulation type"));
  477.                                         break;
  478.                                     case eLFOAdditive:
  479.                                         ListNode->GenFunction = &AddPosTriangle;
  480.                                         break;
  481.                                     case eLFOMultiplicative:
  482.                                         ListNode->GenFunction = &MultPosTriangle;
  483.                                         break;
  484.                                     case eLFOInverseMultiplicative:
  485.                                         ListNode->GenFunction = &InvMultPosTriangle;
  486.                                         break;
  487.                                 }
  488.                             break;
  489.                         case eLFOSignedSquare:
  490.                             switch (ListNode->ModulationMethod)
  491.                                 {
  492.                                     default:
  493.                                         EXECUTE(PRERR(ForceAbort,"NewLFOGenerator:  bad modulation type"));
  494.                                         break;
  495.                                     case eLFOAdditive:
  496.                                         ListNode->GenFunction = &AddSignSquare;
  497.                                         break;
  498.                                     case eLFOMultiplicative:
  499.                                         ListNode->GenFunction = &MultSignSquare;
  500.                                         break;
  501.                                     case eLFOInverseMultiplicative:
  502.                                         ListNode->GenFunction = &InvMultSignSquare;
  503.                                         break;
  504.                                 }
  505.                             break;
  506.                         case eLFOPositiveSquare:
  507.                             switch (ListNode->ModulationMethod)
  508.                                 {
  509.                                     default:
  510.                                         EXECUTE(PRERR(ForceAbort,"NewLFOGenerator:  bad modulation type"));
  511.                                         break;
  512.                                     case eLFOAdditive:
  513.                                         ListNode->GenFunction = &AddPosSquare;
  514.                                         break;
  515.                                     case eLFOMultiplicative:
  516.                                         ListNode->GenFunction = &MultPosSquare;
  517.                                         break;
  518.                                     case eLFOInverseMultiplicative:
  519.                                         ListNode->GenFunction = &InvMultPosSquare;
  520.                                         break;
  521.                                 }
  522.                             break;
  523.                         case eLFOSignedRamp:
  524.                             switch (ListNode->ModulationMethod)
  525.                                 {
  526.                                     default:
  527.                                         EXECUTE(PRERR(ForceAbort,"NewLFOGenerator:  bad modulation type"));
  528.                                         break;
  529.                                     case eLFOAdditive:
  530.                                         ListNode->GenFunction = &AddSignRamp;
  531.                                         break;
  532.                                     case eLFOMultiplicative:
  533.                                         ListNode->GenFunction = &MultSignRamp;
  534.                                         break;
  535.                                     case eLFOInverseMultiplicative:
  536.                                         ListNode->GenFunction = &InvMultSignRamp;
  537.                                         break;
  538.                                 }
  539.                             break;
  540.                         case eLFOPositiveRamp:
  541.                             switch (ListNode->ModulationMethod)
  542.                                 {
  543.                                     default:
  544.                                         EXECUTE(PRERR(ForceAbort,"NewLFOGenerator:  bad modulation type"));
  545.                                         break;
  546.                                     case eLFOAdditive:
  547.                                         ListNode->GenFunction = &AddPosRamp;
  548.                                         break;
  549.                                     case eLFOMultiplicative:
  550.                                         ListNode->GenFunction = &MultPosRamp;
  551.                                         break;
  552.                                     case eLFOInverseMultiplicative:
  553.                                         ListNode->GenFunction = &InvMultPosRamp;
  554.                                         break;
  555.                                 }
  556.                             break;
  557.                         case eLFOSignedLinearFuzzTriangle:
  558.                             switch (ListNode->ModulationMethod)
  559.                                 {
  560.                                     default:
  561.                                         EXECUTE(PRERR(ForceAbort,"NewLFOGenerator:  bad modulation type"));
  562.                                         break;
  563.                                     case eLFOAdditive:
  564.                                         ListNode->GenFunction = &AddSignFuzzTriangle;
  565.                                         break;
  566.                                     case eLFOMultiplicative:
  567.                                         ListNode->GenFunction = &MultSignFuzzTriangle;
  568.                                         break;
  569.                                     case eLFOInverseMultiplicative:
  570.                                         ListNode->GenFunction = &InvMultSignFuzzTriangle;
  571.                                         break;
  572.                                 }
  573.                             break;
  574.                         case eLFOSignedLinearFuzzSquare:
  575.                             switch (ListNode->ModulationMethod)
  576.                                 {
  577.                                     default:
  578.                                         EXECUTE(PRERR(ForceAbort,"NewLFOGenerator:  bad modulation type"));
  579.                                         break;
  580.                                     case eLFOAdditive:
  581.                                         ListNode->GenFunction = &AddSignFuzzSquare;
  582.                                         break;
  583.                                     case eLFOMultiplicative:
  584.                                         ListNode->GenFunction = &MultSignFuzzSquare;
  585.                                         break;
  586.                                     case eLFOInverseMultiplicative:
  587.                                         ListNode->GenFunction = &InvMultSignFuzzSquare;
  588.                                         break;
  589.                                 }
  590.                             break;
  591.                         case eLFOPositiveLinearFuzzTriangle:
  592.                             switch (ListNode->ModulationMethod)
  593.                                 {
  594.                                     default:
  595.                                         EXECUTE(PRERR(ForceAbort,"NewLFOGenerator:  bad modulation type"));
  596.                                         break;
  597.                                     case eLFOAdditive:
  598.                                         ListNode->GenFunction = &AddPosFuzzTriangle;
  599.                                         break;
  600.                                     case eLFOMultiplicative:
  601.                                         ListNode->GenFunction = &MultPosFuzzTriangle;
  602.                                         break;
  603.                                     case eLFOInverseMultiplicative:
  604.                                         ListNode->GenFunction = &InvMultPosFuzzTriangle;
  605.                                         break;
  606.                                 }
  607.                             break;
  608.                         case eLFOPositiveLinearFuzzSquare:
  609.                             switch (ListNode->ModulationMethod)
  610.                                 {
  611.                                     default:
  612.                                         EXECUTE(PRERR(ForceAbort,"NewLFOGenerator:  bad modulation type"));
  613.                                         break;
  614.                                     case eLFOAdditive:
  615.                                         ListNode->GenFunction = &AddPosFuzzSquare;
  616.                                         break;
  617.                                     case eLFOMultiplicative:
  618.                                         ListNode->GenFunction = &MultPosFuzzSquare;
  619.                                         break;
  620.                                     case eLFOInverseMultiplicative:
  621.                                         ListNode->GenFunction = &InvMultPosFuzzSquare;
  622.                                         break;
  623.                                 }
  624.                             break;
  625.                         case eLFOWaveTable:
  626.                             switch (ListNode->ModulationMethod)
  627.                                 {
  628.                                     default:
  629.                                         EXECUTE(PRERR(ForceAbort,"NewLFOGenerator:  bad modulation type"));
  630.                                         break;
  631.                                     case eLFOAdditive:
  632.                                         ListNode->GenFunction = &AddWaveTable;
  633.                                         break;
  634.                                     case eLFOMultiplicative:
  635.                                         ListNode->GenFunction = &MultWaveTable;
  636.                                         break;
  637.                                     case eLFOInverseMultiplicative:
  638.                                         ListNode->GenFunction = &InvMultWaveTable;
  639.                                         break;
  640.                                 }
  641.                             ListNode->WaveTableSourceSelector = NewMultisampleWaveTable(
  642.                                 GetLFOSpecSampleSelector(OneLFOSpec));
  643.                             if (ListNode->WaveTableSourceSelector == NIL)
  644.                                 {
  645.                                  FailurePoint4:
  646.                                     if (ListNode->Operator == eLFOWaveTable)
  647.                                         {
  648.                                             DisposeEnvelopeStateRecord(ListNode->LFOAmplitudeEnvelope);
  649.                                         }
  650.                                     goto FailurePoint3;
  651.                                 }
  652.                             ListNode->WaveTableWasDefined = GetMultisampleReferenceWaveTable(
  653.                                 ListNode->WaveTableSourceSelector,FreqForMultisampling,
  654.                                 &(ListNode->WaveTableMatrix),&(ListNode->FramesPerTable),
  655.                                 &(ListNode->NumberOfTables),&(ListNode->TableNumBits));
  656.                             if (ListNode->WaveTableWasDefined)
  657.                                 {
  658.                                     switch (ListNode->TableNumBits)
  659.                                         {
  660.                                             default:
  661.                                                 EXECUTE(PRERR(ForceAbort,"NewLFOGenerator:  bad num bits"));
  662.                                                 break;
  663.                                             case eSample8bit:
  664.                                                 ListNode->WaveIndexer = (signed long (*)(float,
  665.                                                     FastFixedType,long,long,void**))&WaveTable8Bit;
  666.                                                 break;
  667.                                             case eSample16bit:
  668.                                                 ListNode->WaveIndexer = (signed long (*)(float,
  669.                                                     FastFixedType,long,long,void**))&WaveTable16Bit;
  670.                                                 break;
  671.                                         }
  672.                                 }
  673.                             ListNode->WaveTableIndexEnvelope = NewEnvelopeStateRecord(
  674.                                 GetLFOSpecWaveTableIndexEnvelope(OneLFOSpec),Accent1,Accent2,Accent3,
  675.                                 Accent4,FrequencyHertz,1,HurryUp,TicksPerSecond,&PreOriginTime);
  676.                             if (ListNode->WaveTableIndexEnvelope == NIL)
  677.                                 {
  678.                                  FailurePoint5:
  679.                                     if (ListNode->Operator == eLFOWaveTable)
  680.                                         {
  681.                                             DisposeMultisample(ListNode->WaveTableSourceSelector);
  682.                                         }
  683.                                     goto FailurePoint4;
  684.                                 }
  685.                             if (PreOriginTime > MaxPreOrigin)
  686.                                 {
  687.                                     MaxPreOrigin = PreOriginTime;
  688.                                 }
  689.                             break;
  690.                     }
  691.                 /* set up special values */
  692.                 ListNode->ExtraValue = GetLFOSpecExtraValue(OneLFOSpec);
  693.                 ListNode->TicksPerSecond = TicksPerSecond;
  694.                 if ((ListNode->Operator == eLFOSignedLinearFuzzTriangle)
  695.                     || (ListNode->Operator == eLFOPositiveLinearFuzzTriangle)
  696.                     || (ListNode->Operator == eLFOSignedLinearFuzzSquare)
  697.                     || (ListNode->Operator == eLFOPositiveLinearFuzzSquare))
  698.                     {
  699.                         long                                    OldSeed;
  700.                         long                                    StartingSeed;
  701.  
  702.                         StartingSeed = GetLFOSpecExtraValue(OneLFOSpec);
  703.                         if (StartingSeed < PARKANDMILLERMINIMUM)
  704.                             {
  705.                                 StartingSeed = PARKANDMILLERMINIMUM;
  706.                             }
  707.                         if (StartingSeed > PARKANDMILLERMAXIMUM)
  708.                             {
  709.                                 StartingSeed = PARKANDMILLERMAXIMUM;
  710.                             }
  711.                         OldSeed = SetParkAndMillerRandomSeed(StartingSeed);
  712.                         ListNode->LeftNoise = ((float)ParkAndMillerRandom() - PARKANDMILLERMINIMUM)
  713.                             / (PARKANDMILLERMAXIMUM - PARKANDMILLERMINIMUM - 1);
  714.                         ListNode->RightNoise = ((float)ParkAndMillerRandom() - PARKANDMILLERMINIMUM)
  715.                             / (PARKANDMILLERMAXIMUM - PARKANDMILLERMINIMUM - 1);
  716.                         ListNode->RandomSeed = SetParkAndMillerRandomSeed(OldSeed);
  717.                     }
  718.                 /* link it in */
  719.                 ListNode->Next = NIL;
  720.                 if (ListTail != NIL)
  721.                     {
  722.                         ListTail->Next = ListNode;
  723.                     }
  724.                  else
  725.                     {
  726.                         LFOGen->LFOList = ListNode;
  727.                     }
  728.                 ListTail = ListNode;
  729.             }
  730.  
  731.         *MaxPreOriginTime = MaxPreOrigin;
  732.         return LFOGen;
  733.     }
  734.  
  735.  
  736. /* fix up the origin time so that envelopes start at the proper times */
  737. void                                LFOGeneratorFixEnvelopeOrigins(LFOGenRec* LFOGen,
  738.                                             long ActualPreOriginTime)
  739.     {
  740.         LFOOneStateRec*        Scan;
  741.  
  742.         CheckPtrExistence(LFOGen);
  743.         ValidateLFOGen(LFOGen);
  744.  
  745.         Scan = LFOGen->LFOList;
  746.         while (Scan != NIL)
  747.             {
  748.                 ValidateLFOOneState(Scan);
  749.                 EnvelopeStateFixUpInitialDelay(Scan->LFOAmplitudeEnvelope,ActualPreOriginTime);
  750.                 EnvelopeStateFixUpInitialDelay(Scan->LFOFrequencyEnvelope,ActualPreOriginTime);
  751.                 if (Scan->Operator == eLFOWaveTable)
  752.                     {
  753.                         EnvelopeStateFixUpInitialDelay(Scan->WaveTableIndexEnvelope,
  754.                             ActualPreOriginTime);
  755.                     }
  756.                 Scan = Scan->Next;
  757.             }
  758.     }
  759.  
  760.  
  761. /* this function computes one LFO cycle and returns the value from the LFO generator. */
  762. /* it should be called on the envelope clock. */
  763. FastFixedType                LFOGenUpdateCycle(LFOGenRec* LFOGen, FastFixedType OriginalValue)
  764.     {
  765.         LFOOneStateRec*        Scan;
  766.  
  767.         CheckPtrExistence(LFOGen);
  768.         ValidateLFOGen(LFOGen);
  769.  
  770.         Scan = LFOGen->LFOList;
  771.         if (Scan != NIL)
  772.             {
  773.                 float                            Iterator;
  774.  
  775.                 Iterator = FastFixed2Float(OriginalValue);
  776.                 while (Scan != NIL)
  777.                     {
  778.                         /* perform the calculations */
  779.                         switch (Scan->ModulationMode)
  780.                             {
  781.                                 default:
  782.                                     EXECUTE(PRERR(AllowResume,
  783.                                         "LFOGenUpdateCycle:  bad value for ModulationMode"));
  784.                                     break;
  785.                                 case eLFOArithAdditive:
  786.                                     Iterator = (*Scan->GenFunction)(Scan,FastFixed2Float(
  787.                                         Scan->CurrentPhase),Iterator,FastFixed2Float(EnvelopeUpdate(
  788.                                         Scan->LFOAmplitudeEnvelope)));
  789.                                     break;
  790.                                 case eLFOArithGeometric:
  791.                                     {
  792.                                         MyBoolean                    Sign;
  793.  
  794.                                         Sign = (Iterator < 0);
  795.                                         if (Sign)
  796.                                             {
  797.                                                 Iterator = - Iterator;
  798.                                             }
  799.                                         if (Iterator != 0)
  800.                                             {
  801.                                                 /* the LOG2 is to normalize the values, so that 1/12 will */
  802.                                                 /* be 1 halfstep */
  803.                                                 Iterator = (float)FEXP((*Scan->GenFunction)(Scan,
  804.                                                     FastFixed2Float(Scan->CurrentPhase),(float)FLN(Iterator),
  805.                                                     FastFixed2Float(EnvelopeUpdate(
  806.                                                     Scan->LFOAmplitudeEnvelope)) * (float)LOG2));
  807.                                             }
  808.                                         if (Sign)
  809.                                             {
  810.                                                 Iterator = - Iterator;
  811.                                             }
  812.                                     }
  813.                                     break;
  814.                                 case eLFOArithHalfSteps:
  815.                                     {
  816.                                         MyBoolean                    Sign;
  817.  
  818.                                         Sign = (Iterator < 0);
  819.                                         if (Sign)
  820.                                             {
  821.                                                 Iterator = - Iterator;
  822.                                             }
  823.                                         if (Iterator != 0)
  824.                                             {
  825.                                                 /* the LOG2 is to normalize the values, so that 1/12 will */
  826.                                                 /* be 1 halfstep */
  827.                                                 Iterator = (float)FEXP((*Scan->GenFunction)(Scan,
  828.                                                     FastFixed2Float(Scan->CurrentPhase),(float)FLN(Iterator),
  829.                                                     FastFixed2Float(EnvelopeUpdate(
  830.                                                     Scan->LFOAmplitudeEnvelope)) * (float)LOG2 / 12));
  831.                                             }
  832.                                         if (Sign)
  833.                                             {
  834.                                                 Iterator = - Iterator;
  835.                                             }
  836.                                     }
  837.                                     break;
  838.                             }
  839.                         Scan->CurrentPhase = Scan->CurrentPhase  + (float)EnvelopeUpdate(
  840.                             Scan->LFOFrequencyEnvelope) / LFOGen->EnvelopeTicksPerSecond;
  841.                         if ((Scan->Operator == eLFOSignedLinearFuzzTriangle)
  842.                             || (Scan->Operator == eLFOPositiveLinearFuzzTriangle)
  843.                             || (Scan->Operator == eLFOSignedLinearFuzzSquare)
  844.                             || (Scan->Operator == eLFOPositiveLinearFuzzSquare))
  845.                             {
  846.                                 long                            Counter;
  847.                                 long                            OldSeed;
  848.  
  849.                                 OldSeed = SetParkAndMillerRandomSeed(Scan->RandomSeed);
  850.                                 for (Counter = Scan->CurrentPhase >> FASTFIXEDPRECISION;
  851.                                     Counter >= 1; Counter -= 1)
  852.                                     {
  853.                                         Scan->LeftNoise = Scan->RightNoise;
  854.                                         Scan->RightNoise = ((float)ParkAndMillerRandom()
  855.                                             - PARKANDMILLERMINIMUM) / (PARKANDMILLERMAXIMUM
  856.                                             - PARKANDMILLERMINIMUM - 1);
  857.                                     }
  858.                                 Scan->RandomSeed = SetParkAndMillerRandomSeed(OldSeed);
  859.                             }
  860.                         Scan->CurrentPhase = Scan->CurrentPhase & ((1L << FASTFIXEDPRECISION) - 1);
  861.                         /* go to next one */
  862.                         Scan = Scan->Next;
  863.                     }
  864.                 return Double2FastFixed(Iterator);
  865.             }
  866.          else
  867.             {
  868.                 return OriginalValue;
  869.             }
  870.     }
  871.  
  872.  
  873. /* pass the key-up impulse on to the envelopes contained inside */
  874. void                                LFOGeneratorKeyUpSustain1(LFOGenRec* LFOGen)
  875.     {
  876.         LFOOneStateRec*        Scan;
  877.  
  878.         CheckPtrExistence(LFOGen);
  879.         ValidateLFOGen(LFOGen);
  880.  
  881.         Scan = LFOGen->LFOList;
  882.         while (Scan != NIL)
  883.             {
  884.                 EnvelopeKeyUpSustain1(Scan->LFOAmplitudeEnvelope);
  885.                 EnvelopeKeyUpSustain1(Scan->LFOFrequencyEnvelope);
  886.                 if (Scan->Operator == eLFOWaveTable)
  887.                     {
  888.                         EnvelopeKeyUpSustain1(Scan->WaveTableIndexEnvelope);
  889.                     }
  890.                 Scan = Scan->Next;
  891.             }
  892.     }
  893.  
  894.  
  895. /* pass the key-up impulse on to the envelopes contained inside */
  896. void                                LFOGeneratorKeyUpSustain2(LFOGenRec* LFOGen)
  897.     {
  898.         LFOOneStateRec*        Scan;
  899.  
  900.         CheckPtrExistence(LFOGen);
  901.         ValidateLFOGen(LFOGen);
  902.  
  903.         Scan = LFOGen->LFOList;
  904.         while (Scan != NIL)
  905.             {
  906.                 EnvelopeKeyUpSustain2(Scan->LFOAmplitudeEnvelope);
  907.                 EnvelopeKeyUpSustain2(Scan->LFOFrequencyEnvelope);
  908.                 if (Scan->Operator == eLFOWaveTable)
  909.                     {
  910.                         EnvelopeKeyUpSustain2(Scan->WaveTableIndexEnvelope);
  911.                     }
  912.                 Scan = Scan->Next;
  913.             }
  914.     }
  915.  
  916.  
  917. /* pass the key-up impulse on to the envelopes contained inside */
  918. void                                LFOGeneratorKeyUpSustain3(LFOGenRec* LFOGen)
  919.     {
  920.         LFOOneStateRec*        Scan;
  921.  
  922.         CheckPtrExistence(LFOGen);
  923.         ValidateLFOGen(LFOGen);
  924.  
  925.         Scan = LFOGen->LFOList;
  926.         while (Scan != NIL)
  927.             {
  928.                 EnvelopeKeyUpSustain3(Scan->LFOAmplitudeEnvelope);
  929.                 EnvelopeKeyUpSustain3(Scan->LFOFrequencyEnvelope);
  930.                 if (Scan->Operator == eLFOWaveTable)
  931.                     {
  932.                         EnvelopeKeyUpSustain3(Scan->WaveTableIndexEnvelope);
  933.                     }
  934.                 Scan = Scan->Next;
  935.             }
  936.     }
  937.  
  938.  
  939. /* retrigger envelopes from the origin point */
  940. void                                LFOGeneratorRetriggerFromOrigin(LFOGenRec* LFOGen, float Accent1,
  941.                                             float Accent2, float Accent3, float Accent4, float FrequencyHertz,
  942.                                             float HurryUp, float AmplitudeScaling, float FrequencyScaling,
  943.                                             MyBoolean ActuallyRetrigger)
  944.     {
  945.         LFOOneStateRec*        Scan;
  946.  
  947.         CheckPtrExistence(LFOGen);
  948.         ValidateLFOGen(LFOGen);
  949.  
  950.         Scan = LFOGen->LFOList;
  951.         while (Scan != NIL)
  952.             {
  953.                 EnvelopeRetriggerFromOrigin(Scan->LFOAmplitudeEnvelope,Accent1,Accent2,
  954.                     Accent3,Accent4,FrequencyHertz,AmplitudeScaling,HurryUp,
  955.                     LFOGen->EnvelopeTicksPerSecond,ActuallyRetrigger);
  956.                 EnvelopeRetriggerFromOrigin(Scan->LFOFrequencyEnvelope,Accent1,Accent2,
  957.                     Accent3,Accent4,FrequencyHertz,FrequencyScaling,HurryUp,
  958.                     LFOGen->EnvelopeTicksPerSecond,ActuallyRetrigger);
  959.                 if (Scan->Operator == eLFOWaveTable)
  960.                     {
  961.                         EnvelopeRetriggerFromOrigin(Scan->WaveTableIndexEnvelope,Accent1,Accent2,
  962.                             Accent3,Accent4,FrequencyHertz,FrequencyScaling,HurryUp,
  963.                             LFOGen->EnvelopeTicksPerSecond,ActuallyRetrigger);
  964.                     }
  965.                 Scan = Scan->Next;
  966.             }
  967.     }
  968.  
  969.  
  970. /* dispose the LFO generator */
  971. void                                DisposeLFOGenerator(LFOGenRec* LFOGen)
  972.     {
  973.         LFOOneStateRec*        StateScan;
  974.  
  975.         CheckPtrExistence(LFOGen);
  976.         ValidateLFOGen(LFOGen);
  977.  
  978.         StateScan = LFOGen->LFOList;
  979.  
  980.         /* dispose of the master record */
  981.         LFOGen->GarbageLink = LFOGenFreeList;
  982.         LFOGenFreeList = LFOGen;
  983.  
  984.         /* dispose of each element */
  985.         while (StateScan != NIL)
  986.             {
  987.                 LFOOneStateRec*        Temp;
  988.  
  989.                 ValidateLFOOneState(StateScan);
  990.                 if (StateScan->Operator == eLFOWaveTable)
  991.                     {
  992.                         DisposeMultisample(StateScan->WaveTableSourceSelector);
  993.                         DisposeEnvelopeStateRecord(StateScan->WaveTableIndexEnvelope);
  994.                     }
  995.                 DisposeEnvelopeStateRecord(StateScan->LFOAmplitudeEnvelope);
  996.                 DisposeEnvelopeStateRecord(StateScan->LFOFrequencyEnvelope);
  997.                 Temp = StateScan;
  998.                 StateScan = StateScan->Next;
  999.                 Temp->Next = LFOOneStateFreeList;
  1000.                 LFOOneStateFreeList = Temp;
  1001.             }
  1002.     }
  1003.  
  1004.  
  1005. /* find out if LFO generator has started yet */
  1006. MyBoolean                        HasLFOGeneratorStarted(LFOGenRec* LFOGen)
  1007.     {
  1008.         LFOOneStateRec*        StateScan;
  1009.  
  1010.         CheckPtrExistence(LFOGen);
  1011.         ValidateLFOGen(LFOGen);
  1012.         StateScan = LFOGen->LFOList;
  1013.         while (StateScan != NIL)
  1014.             {
  1015.                 ValidateLFOOneState(StateScan);
  1016.                 if (StateScan->Operator == eLFOWaveTable)
  1017.                     {
  1018.                         if (HasEnvelopeStartedYet(StateScan->WaveTableIndexEnvelope))
  1019.                             {
  1020.                                 return True;
  1021.                             }
  1022.                     }
  1023.                 if (HasEnvelopeStartedYet(StateScan->LFOAmplitudeEnvelope))
  1024.                     {
  1025.                         return True;
  1026.                     }
  1027.                 if (HasEnvelopeStartedYet(StateScan->LFOFrequencyEnvelope))
  1028.                     {
  1029.                         return True;
  1030.                     }
  1031.                 StateScan = StateScan->Next;
  1032.             }
  1033.         return False;
  1034.     }
  1035.  
  1036.  
  1037. static float                        AddConst(LFOOneStateRec* State, float Phase,
  1038.                                                     float OriginalValue, float Amplitude)
  1039.     {
  1040.         return OriginalValue + Amplitude;
  1041.     }
  1042.  
  1043.  
  1044. static float                        AddSignSine(LFOOneStateRec* State, float Phase,
  1045.                                                     float OriginalValue, float Amplitude)
  1046.     {
  1047.         return OriginalValue + Amplitude * FSIN(Phase * TWOPI);
  1048.     }
  1049.  
  1050.  
  1051. static float                        AddPosSine(LFOOneStateRec* State, float Phase,
  1052.                                                     float OriginalValue, float Amplitude)
  1053.     {
  1054.         return OriginalValue + Amplitude * 0.5 * (1 + FSIN(Phase * TWOPI));
  1055.     }
  1056.  
  1057.  
  1058. static float                        AddSignTriangle(LFOOneStateRec* State, float Phase,
  1059.                                                     float OriginalValue, float Amplitude)
  1060.     {
  1061.         if (Phase < 0.25)
  1062.             {
  1063.             }
  1064.         else if (Phase < 0.75)
  1065.             {
  1066.                 Phase = 0.5 - Phase;
  1067.             }
  1068.         else
  1069.             {
  1070.                 Phase = Phase - 1;
  1071.             }
  1072.         return OriginalValue + Phase * 4 * Amplitude;
  1073.     }
  1074.  
  1075.  
  1076. static float                        AddPosTriangle(LFOOneStateRec* State, float Phase,
  1077.                                                     float OriginalValue, float Amplitude)
  1078.     {
  1079.         if (Phase < 0.25)
  1080.             {
  1081.             }
  1082.         else if (Phase < 0.75)
  1083.             {
  1084.                 Phase = 0.5 - Phase;
  1085.             }
  1086.         else
  1087.             {
  1088.                 Phase = Phase - 1;
  1089.             }
  1090.         return OriginalValue + (Phase + .25) * 2 * Amplitude;
  1091.     }
  1092.  
  1093.  
  1094. static float                        AddSignSquare(LFOOneStateRec* State, float Phase,
  1095.                                                     float OriginalValue, float Amplitude)
  1096.     {
  1097.         float                                    Peak1;
  1098.         float                                    Peak2;
  1099.         float                                    Trough1;
  1100.         float                                    Trough2;
  1101.  
  1102.         Peak1 = State->ExtraValue / 4;
  1103.         if (Phase < Peak1)
  1104.             {
  1105.                 return OriginalValue + Amplitude * (Phase / Peak1);
  1106.             }
  1107.         Peak2 = Peak1 + (.5 - State->ExtraValue / 2);
  1108.         if (Phase < Peak2)
  1109.             {
  1110.                 return OriginalValue + Amplitude;
  1111.             }
  1112.         Trough1 = Peak2 + State->ExtraValue / 2;
  1113.         if (Phase < Trough1)
  1114.             {
  1115.                 return OriginalValue + Amplitude * ((Trough1 - Phase) / Peak1 - 1);
  1116.             }
  1117.         Trough2 = 1 - State->ExtraValue / 4;
  1118.         if (Phase < Trough2)
  1119.             {
  1120.                 return OriginalValue - Amplitude;
  1121.             }
  1122.         return OriginalValue + Amplitude * ((Phase - Trough2) / (State->ExtraValue / 4) - 1);
  1123.     }
  1124.  
  1125.  
  1126. static float                        AddPosSquare(LFOOneStateRec* State, float Phase,
  1127.                                                     float OriginalValue, float Amplitude)
  1128.     {
  1129.         float                                    Peak1;
  1130.         float                                    Peak2;
  1131.         float                                    Trough1;
  1132.         float                                    Trough2;
  1133.  
  1134.         Peak1 = State->ExtraValue / 4;
  1135.         if (Phase < Peak1)
  1136.             {
  1137.                 return OriginalValue + Amplitude * .5 * (1 + (Phase / Peak1));
  1138.             }
  1139.         Peak2 = Peak1 + (.5 - State->ExtraValue / 2);
  1140.         if (Phase < Peak2)
  1141.             {
  1142.                 return OriginalValue + Amplitude;
  1143.             }
  1144.         Trough1 = Peak2 + State->ExtraValue / 2;
  1145.         if (Phase < Trough1)
  1146.             {
  1147.                 return OriginalValue + Amplitude * .5 * (1 + ((Trough1 - Phase) / Peak1 - 1));
  1148.             }
  1149.         Trough2 = 1 - State->ExtraValue / 4;
  1150.         if (Phase < Trough2)
  1151.             {
  1152.                 return OriginalValue;
  1153.             }
  1154.         return OriginalValue + Amplitude * .5 * (1 + ((Phase - Trough2)
  1155.             / (State->ExtraValue / 4) - 1));
  1156.     }
  1157.  
  1158.  
  1159. static float                        AddSignRamp(LFOOneStateRec* State, float Phase,
  1160.                                                     float OriginalValue, float Amplitude)
  1161.     {
  1162.         if (Phase < State->ExtraValue)
  1163.             {
  1164.                 return OriginalValue + Amplitude * (1 - 2 * (Phase / State->ExtraValue));
  1165.             }
  1166.          else
  1167.             {
  1168.                 return OriginalValue + Amplitude * (2 * ((Phase - State->ExtraValue)
  1169.                     / (1 - State->ExtraValue)) - 1);
  1170.             }
  1171.     }
  1172.  
  1173.  
  1174. static float                        AddPosRamp(LFOOneStateRec* State, float Phase,
  1175.                                                     float OriginalValue, float Amplitude)
  1176.     {
  1177.         if (Phase < State->ExtraValue)
  1178.             {
  1179.                 return OriginalValue + Amplitude * (1 - Phase / State->ExtraValue);
  1180.             }
  1181.          else
  1182.             {
  1183.                 return OriginalValue + Amplitude * ((Phase - State->ExtraValue)
  1184.                     / (1 - State->ExtraValue));
  1185.             }
  1186.     }
  1187.  
  1188.  
  1189. static float                        AddSignFuzzTriangle(LFOOneStateRec* State, float Phase,
  1190.                                                     float OriginalValue, float Amplitude)
  1191.     {
  1192.         float                                    ReturnValue;
  1193.  
  1194.         ReturnValue = State->LeftNoise * (1 - Phase) + State->RightNoise * Phase;
  1195.         return OriginalValue + (2 * ReturnValue - 1) * Amplitude;
  1196.     }
  1197.  
  1198.  
  1199. static float                        AddSignFuzzSquare(LFOOneStateRec* State, float Phase,
  1200.                                                     float OriginalValue, float Amplitude)
  1201.     {
  1202.         float                                    ReturnValue;
  1203.  
  1204.         ReturnValue = State->LeftNoise;
  1205.         return OriginalValue + (2 * ReturnValue - 1) * Amplitude;
  1206.     }
  1207.  
  1208.  
  1209. static float                        AddPosFuzzTriangle(LFOOneStateRec* State, float Phase,
  1210.                                                     float OriginalValue, float Amplitude)
  1211.     {
  1212.         float                                    ReturnValue;
  1213.  
  1214.         ReturnValue = State->LeftNoise * (1 - Phase) + State->RightNoise * Phase;
  1215.         return OriginalValue + ReturnValue * Amplitude;
  1216.     }
  1217.  
  1218.  
  1219. static float                        AddPosFuzzSquare(LFOOneStateRec* State, float Phase,
  1220.                                                     float OriginalValue, float Amplitude)
  1221.     {
  1222.         float                                    ReturnValue;
  1223.  
  1224.         ReturnValue = State->LeftNoise;
  1225.         return OriginalValue + ReturnValue * Amplitude;
  1226.     }
  1227.  
  1228.  
  1229. static float                        MultConst(LFOOneStateRec* State, float Phase,
  1230.                                                     float OriginalValue, float Amplitude)
  1231.     {
  1232.         return OriginalValue * Amplitude;
  1233.     }
  1234.  
  1235.  
  1236. static float                        MultSignSine(LFOOneStateRec* State, float Phase,
  1237.                                                     float OriginalValue, float Amplitude)
  1238.     {
  1239.         return OriginalValue * Amplitude * FSIN(Phase * TWOPI);
  1240.     }
  1241.  
  1242.  
  1243. static float                        MultPosSine(LFOOneStateRec* State, float Phase,
  1244.                                                     float OriginalValue, float Amplitude)
  1245.     {
  1246.         return OriginalValue * Amplitude * 0.5 * (1 + FSIN(Phase * TWOPI));
  1247.     }
  1248.  
  1249.  
  1250. static float                        MultSignTriangle(LFOOneStateRec* State, float Phase,
  1251.                                                     float OriginalValue, float Amplitude)
  1252.     {
  1253.         if (Phase < 0.25)
  1254.             {
  1255.             }
  1256.         else if (Phase < 0.75)
  1257.             {
  1258.                 Phase = 0.5 - Phase;
  1259.             }
  1260.         else
  1261.             {
  1262.                 Phase = Phase - 1;
  1263.             }
  1264.         return OriginalValue * Phase * 4 * Amplitude;
  1265.     }
  1266.  
  1267.  
  1268. static float                        MultPosTriangle(LFOOneStateRec* State, float Phase,
  1269.                                                     float OriginalValue, float Amplitude)
  1270.     {
  1271.         if (Phase < 0.25)
  1272.             {
  1273.             }
  1274.         else if (Phase < 0.75)
  1275.             {
  1276.                 Phase = 0.5 - Phase;
  1277.             }
  1278.         else
  1279.             {
  1280.                 Phase = Phase - 1;
  1281.             }
  1282.         return OriginalValue * (Phase + .25) * 2 * Amplitude;
  1283.     }
  1284.  
  1285.  
  1286. static float                        MultSignSquare(LFOOneStateRec* State, float Phase,
  1287.                                                     float OriginalValue, float Amplitude)
  1288.     {
  1289.         float                                    Peak1;
  1290.         float                                    Peak2;
  1291.         float                                    Trough1;
  1292.         float                                    Trough2;
  1293.  
  1294.         Peak1 = State->ExtraValue / 4;
  1295.         if (Phase < Peak1)
  1296.             {
  1297.                 return OriginalValue * Amplitude * (Phase / Peak1);
  1298.             }
  1299.         Peak2 = Peak1 + (.5 - State->ExtraValue / 2);
  1300.         if (Phase < Peak2)
  1301.             {
  1302.                 return OriginalValue * Amplitude;
  1303.             }
  1304.         Trough1 = Peak2 + State->ExtraValue / 2;
  1305.         if (Phase < Trough1)
  1306.             {
  1307.                 return OriginalValue * Amplitude * ((Trough1 - Phase) / Peak1 - 1);
  1308.             }
  1309.         Trough2 = 1 - State->ExtraValue / 4;
  1310.         if (Phase < Trough2)
  1311.             {
  1312.                 return OriginalValue * - Amplitude;
  1313.             }
  1314.         return OriginalValue * Amplitude * ((Phase - Trough2) / (State->ExtraValue / 4) - 1);
  1315.     }
  1316.  
  1317.  
  1318. static float                        MultPosSquare(LFOOneStateRec* State, float Phase,
  1319.                                                     float OriginalValue, float Amplitude)
  1320.     {
  1321.         float                                    Peak1;
  1322.         float                                    Peak2;
  1323.         float                                    Trough1;
  1324.         float                                    Trough2;
  1325.  
  1326.         Peak1 = State->ExtraValue / 4;
  1327.         if (Phase < Peak1)
  1328.             {
  1329.                 return OriginalValue * Amplitude * .5 * (1 + (Phase / Peak1));
  1330.             }
  1331.         Peak2 = Peak1 + (.5 - State->ExtraValue / 2);
  1332.         if (Phase < Peak2)
  1333.             {
  1334.                 return OriginalValue * Amplitude;
  1335.             }
  1336.         Trough1 = Peak2 + State->ExtraValue / 2;
  1337.         if (Phase < Trough1)
  1338.             {
  1339.                 return OriginalValue * Amplitude * .5 * (1 + ((Trough1 - Phase) / Peak1 - 1));
  1340.             }
  1341.         Trough2 = 1 - State->ExtraValue / 4;
  1342.         if (Phase < Trough2)
  1343.             {
  1344.                 return 0;
  1345.             }
  1346.         return OriginalValue * Amplitude * .5 * (1 + ((Phase - Trough2)
  1347.             / (State->ExtraValue / 4) - 1));
  1348.     }
  1349.  
  1350.  
  1351. static float                        MultSignRamp(LFOOneStateRec* State, float Phase,
  1352.                                                     float OriginalValue, float Amplitude)
  1353.     {
  1354.         if (Phase < State->ExtraValue)
  1355.             {
  1356.                 return OriginalValue * Amplitude * (1 - 2 * (Phase / State->ExtraValue));
  1357.             }
  1358.          else
  1359.             {
  1360.                 return OriginalValue * Amplitude * (2 * ((Phase - State->ExtraValue)
  1361.                     / (1 - State->ExtraValue)) - 1);
  1362.             }
  1363.     }
  1364.  
  1365.  
  1366. static float                        MultPosRamp(LFOOneStateRec* State, float Phase,
  1367.                                                     float OriginalValue, float Amplitude)
  1368.     {
  1369.         if (Phase < State->ExtraValue)
  1370.             {
  1371.                 return OriginalValue * Amplitude * (1 - Phase / State->ExtraValue);
  1372.             }
  1373.          else
  1374.             {
  1375.                 return OriginalValue * Amplitude * ((Phase - State->ExtraValue)
  1376.                     / (1 - State->ExtraValue));
  1377.             }
  1378.     }
  1379.  
  1380.  
  1381. static float                        MultSignFuzzTriangle(LFOOneStateRec* State, float Phase,
  1382.                                                     float OriginalValue, float Amplitude)
  1383.     {
  1384.         float                                    ReturnValue;
  1385.  
  1386.         ReturnValue = State->LeftNoise * (1 - Phase) + State->RightNoise * Phase;
  1387.         return OriginalValue * (2 * ReturnValue - 1) * Amplitude;
  1388.     }
  1389.  
  1390.  
  1391. static float                        MultSignFuzzSquare(LFOOneStateRec* State, float Phase,
  1392.                                                     float OriginalValue, float Amplitude)
  1393.     {
  1394.         float                                    ReturnValue;
  1395.  
  1396.         ReturnValue = State->LeftNoise;
  1397.         return OriginalValue * (2 * ReturnValue - 1) * Amplitude;
  1398.     }
  1399.  
  1400.  
  1401. static float                        MultPosFuzzTriangle(LFOOneStateRec* State, float Phase,
  1402.                                                     float OriginalValue, float Amplitude)
  1403.     {
  1404.         float                                    ReturnValue;
  1405.  
  1406.         ReturnValue = State->LeftNoise * (1 - Phase) + State->RightNoise * Phase;
  1407.         return OriginalValue * ReturnValue * Amplitude;
  1408.     }
  1409.  
  1410.  
  1411. static float                        MultPosFuzzSquare(LFOOneStateRec* State, float Phase,
  1412.                                                     float OriginalValue, float Amplitude)
  1413.     {
  1414.         float                                    ReturnValue;
  1415.  
  1416.         ReturnValue = State->LeftNoise;
  1417.         return OriginalValue * ReturnValue * Amplitude;
  1418.     }
  1419.  
  1420.  
  1421. static float                        InvMultConst(LFOOneStateRec* State, float Phase,
  1422.                                                     float OriginalValue, float Amplitude)
  1423.     {
  1424.         return OriginalValue * (1 - Amplitude);
  1425.     }
  1426.  
  1427.  
  1428. static float                        InvMultSignSine(LFOOneStateRec* State, float Phase,
  1429.                                                     float OriginalValue, float Amplitude)
  1430.     {
  1431.         return OriginalValue * (1 - Amplitude * FSIN(Phase * TWOPI));
  1432.     }
  1433.  
  1434.  
  1435. static float                        InvMultPosSine(LFOOneStateRec* State, float Phase,
  1436.                                                     float OriginalValue, float Amplitude)
  1437.     {
  1438.         return OriginalValue * (1 - Amplitude * 0.5 * (1 + FSIN(Phase * TWOPI)));
  1439.     }
  1440.  
  1441.  
  1442. static float                        InvMultSignTriangle(LFOOneStateRec* State, float Phase,
  1443.                                                     float OriginalValue, float Amplitude)
  1444.     {
  1445.         if (Phase < 0.25)
  1446.             {
  1447.             }
  1448.         else if (Phase < 0.75)
  1449.             {
  1450.                 Phase = 0.5 - Phase;
  1451.             }
  1452.         else
  1453.             {
  1454.                 Phase = Phase - 1;
  1455.             }
  1456.         return OriginalValue * (1 - Phase * 4 * Amplitude);
  1457.     }
  1458.  
  1459.  
  1460. static float                        InvMultPosTriangle(LFOOneStateRec* State, float Phase,
  1461.                                                     float OriginalValue, float Amplitude)
  1462.     {
  1463.         if (Phase < 0.25)
  1464.             {
  1465.             }
  1466.         else if (Phase < 0.75)
  1467.             {
  1468.                 Phase = 0.5 - Phase;
  1469.             }
  1470.         else
  1471.             {
  1472.                 Phase = Phase - 1;
  1473.             }
  1474.         return OriginalValue * (1 - ((Phase + .25) * 2 * Amplitude));
  1475.     }
  1476.  
  1477.  
  1478. static float                        InvMultSignSquare(LFOOneStateRec* State, float Phase,
  1479.                                                     float OriginalValue, float Amplitude)
  1480.     {
  1481.         float                                    Peak1;
  1482.         float                                    Peak2;
  1483.         float                                    Trough1;
  1484.         float                                    Trough2;
  1485.  
  1486.         Peak1 = State->ExtraValue / 4;
  1487.         if (Phase < Peak1)
  1488.             {
  1489.                 return OriginalValue * (1 - Amplitude * (Phase / Peak1));
  1490.             }
  1491.         Peak2 = Peak1 + (.5 - State->ExtraValue / 2);
  1492.         if (Phase < Peak2)
  1493.             {
  1494.                 return OriginalValue * (1 - Amplitude);
  1495.             }
  1496.         Trough1 = Peak2 + State->ExtraValue / 2;
  1497.         if (Phase < Trough1)
  1498.             {
  1499.                 return OriginalValue * (1 - Amplitude * ((Trough1 - Phase) / Peak1 - 1));
  1500.             }
  1501.         Trough2 = 1 - State->ExtraValue / 4;
  1502.         if (Phase < Trough2)
  1503.             {
  1504.                 return OriginalValue * (1 - - Amplitude);
  1505.             }
  1506.         return OriginalValue * (1 - Amplitude * ((Phase - Trough2)
  1507.             / (State->ExtraValue / 4) - 1));
  1508.     }
  1509.  
  1510.  
  1511. static float                        InvMultPosSquare(LFOOneStateRec* State, float Phase,
  1512.                                                     float OriginalValue, float Amplitude)
  1513.     {
  1514.         float                                    Peak1;
  1515.         float                                    Peak2;
  1516.         float                                    Trough1;
  1517.         float                                    Trough2;
  1518.  
  1519.         Peak1 = State->ExtraValue / 4;
  1520.         if (Phase < Peak1)
  1521.             {
  1522.                 return OriginalValue * (1 - Amplitude * .5 * (1 + (Phase / Peak1)));
  1523.             }
  1524.         Peak2 = Peak1 + (.5 - State->ExtraValue / 2);
  1525.         if (Phase < Peak2)
  1526.             {
  1527.                 return OriginalValue * (1 - Amplitude);
  1528.             }
  1529.         Trough1 = Peak2 + State->ExtraValue / 2;
  1530.         if (Phase < Trough1)
  1531.             {
  1532.                 return OriginalValue * (1 - Amplitude * .5 * (1 + ((Trough1 - Phase)
  1533.                     / Peak1 - 1)));
  1534.             }
  1535.         Trough2 = 1 - State->ExtraValue / 4;
  1536.         if (Phase < Trough2)
  1537.             {
  1538.                 return OriginalValue * (1 - 0);
  1539.             }
  1540.         return OriginalValue * (1 - Amplitude * .5 * (1 + ((Phase - Trough2)
  1541.             / (State->ExtraValue / 4) - 1)));
  1542.     }
  1543.  
  1544.  
  1545. static float                        InvMultSignRamp(LFOOneStateRec* State, float Phase,
  1546.                                                     float OriginalValue, float Amplitude)
  1547.     {
  1548.         if (Phase < State->ExtraValue)
  1549.             {
  1550.                 return OriginalValue * (1 - Amplitude * (1 - 2 * (Phase / State->ExtraValue)));
  1551.             }
  1552.          else
  1553.             {
  1554.                 return OriginalValue * (1 - Amplitude * (2 * ((Phase - State->ExtraValue)
  1555.                     / (1 - State->ExtraValue)) - 1));
  1556.             }
  1557.     }
  1558.  
  1559.  
  1560. static float                        InvMultPosRamp(LFOOneStateRec* State, float Phase,
  1561.                                                     float OriginalValue, float Amplitude)
  1562.     {
  1563.         if (Phase < State->ExtraValue)
  1564.             {
  1565.                 return OriginalValue * (1 - Amplitude * (1 - Phase / State->ExtraValue));
  1566.             }
  1567.          else
  1568.             {
  1569.                 return OriginalValue * (1 - Amplitude * ((Phase - State->ExtraValue)
  1570.                     / (1 - State->ExtraValue)));
  1571.             }
  1572.     }
  1573.  
  1574.  
  1575. static float                        InvMultSignFuzzTriangle(LFOOneStateRec* State, float Phase,
  1576.                                                     float OriginalValue, float Amplitude)
  1577.     {
  1578.         float                                    ReturnValue;
  1579.  
  1580.         ReturnValue = State->LeftNoise * (1 - Phase) + State->RightNoise * Phase;
  1581.         return OriginalValue * (1 - (2 * ReturnValue - 1) * Amplitude);
  1582.     }
  1583.  
  1584.  
  1585. static float                        InvMultSignFuzzSquare(LFOOneStateRec* State, float Phase,
  1586.                                                     float OriginalValue, float Amplitude)
  1587.     {
  1588.         float                                    ReturnValue;
  1589.  
  1590.         ReturnValue = State->LeftNoise;
  1591.         return OriginalValue * (1 - (2 * ReturnValue - 1) * Amplitude);
  1592.     }
  1593.  
  1594.  
  1595. static float                        InvMultPosFuzzTriangle(LFOOneStateRec* State, float Phase,
  1596.                                                     float OriginalValue, float Amplitude)
  1597.     {
  1598.         float                                    ReturnValue;
  1599.  
  1600.         ReturnValue = State->LeftNoise * (1 - Phase) + State->RightNoise * Phase;
  1601.         return OriginalValue * (1 - ReturnValue * Amplitude);
  1602.     }
  1603.  
  1604.  
  1605. static float                        InvMultPosFuzzSquare(LFOOneStateRec* State, float Phase,
  1606.                                                     float OriginalValue, float Amplitude)
  1607.     {
  1608.         float                                    ReturnValue;
  1609.  
  1610.         ReturnValue = State->LeftNoise;
  1611.         return OriginalValue * (1 - ReturnValue * Amplitude);
  1612.     }
  1613.  
  1614.  
  1615. static float                        AddWaveTable(LFOOneStateRec* State, float Phase,
  1616.                                                     float OriginalValue, float Amplitude)
  1617.     {
  1618.         if (State->WaveTableWasDefined)
  1619.             {
  1620.                 return OriginalValue + Amplitude
  1621.                     * ((float)(*State->WaveIndexer)(State->FramesPerTable * Phase,EnvelopeUpdate(
  1622.                         State->WaveTableIndexEnvelope),State->NumberOfTables,
  1623.                         State->FramesPerTable,State->WaveTableMatrix) / MAX16BIT);
  1624.             }
  1625.          else
  1626.             {
  1627.                 return OriginalValue;
  1628.             }
  1629.     }
  1630.  
  1631.  
  1632. static float                        MultWaveTable(LFOOneStateRec* State, float Phase,
  1633.                                                     float OriginalValue, float Amplitude)
  1634.     {
  1635.         if (State->WaveTableWasDefined)
  1636.             {
  1637.                 return OriginalValue * Amplitude
  1638.                     * ((float)(*State->WaveIndexer)(State->FramesPerTable * Phase,EnvelopeUpdate(
  1639.                         State->WaveTableIndexEnvelope),State->NumberOfTables,
  1640.                         State->FramesPerTable,State->WaveTableMatrix) / MAX16BIT);
  1641.             }
  1642.          else
  1643.             {
  1644.                 return 0;
  1645.             }
  1646.     }
  1647.  
  1648.  
  1649. static float                        InvMultWaveTable(LFOOneStateRec* State, float Phase,
  1650.                                                     float OriginalValue, float Amplitude)
  1651.     {
  1652.         if (State->WaveTableWasDefined)
  1653.             {
  1654.                 return OriginalValue * (1 - Amplitude
  1655.                     * ((float)(*State->WaveIndexer)(State->FramesPerTable * Phase,EnvelopeUpdate(
  1656.                         State->WaveTableIndexEnvelope),State->NumberOfTables,
  1657.                         State->FramesPerTable,State->WaveTableMatrix) / MAX16BIT));
  1658.             }
  1659.          else
  1660.             {
  1661.                 return OriginalValue;
  1662.             }
  1663.     }
  1664.